﻿package com.tudou.newPlayer
{
    import com.tudou.band.*;
    import com.tudou.fast.*;
    import com.tudou.model.*;
    import com.tudou.track.*;
    import com.tudou.utils.*;
    import flash.events.*;
    import flash.utils.*;

    public class BaseTudouPlayer extends VideoPlayer implements IPlayerStatus
    {
        private var _seekSize:Number = 0;
        protected var _isDraging:Boolean = false;
        protected var _iBaseInfo:IBaseInfo;
        private var fastTudou:FastTudouNew;
        protected var startKeyIndex:int = 0;
        protected var _skipTailValue:Number = -1;
        private var fastTimer:Timer;
        private var _aop:AOPTracker;
        private var _startChangeTime:int = 0;
        private var _cndURL:String = "";
        protected var _hasPlayedTime:Number = 0;
        protected var catchedTime:uint;
        protected var basePlayURL:String = "";
        protected var playedKeyIndex:int = 0;
        private var _changeStreamNodeLog:String = "";
        protected var bandManager:BandManager;
        protected var _skipHeadValue:Number = -1;
        protected var _lastCurPlayTime:Number = -1;
        protected var loadedKeyIndex:int = 0;
        private var waittingFast:int = 0;
        protected var isChangedURL:Boolean = false;
        private var _startBufferTime:int = 0;
        protected var _aimSeekValue:Number = -1;

        public function BaseTudouPlayer(param1:uint = 400, param2:uint = 300)
        {
            bandManager = BandManager.inst;
            fastTudou = FastTudouNew.inst;
            _aop = AOPTracker.getInst();
            super(param1, param2);
            return;
        }// end function

        public function get cdnURL() : String
        {
            return _cndURL;
        }// end function

        public function get isPaused() : Boolean
        {
            return _videoStatus.status == VideoStatus.PAUSED;
        }// end function

        override public function get loadSize() : Number
        {
            return Math.max(super.loadSize, 0) + startSize;
        }// end function

        private function bandManagerHlr() : void
        {
            if (!fastTudou.isConnected && _metaData && CDNUtil.isTudouCDN(_playURL))
            {
                bandManager.judge(hasStartPlay, isPlaying, _playURL, startTime, playTime, loadTime, totalTime, _iBaseInfo.isForceBand);
            }
            return;
        }// end function

        public function set aimSeekValue(param1:Number) : void
        {
            _aimSeekValue = param1;
            return;
        }// end function

        override public function get playTime() : Number
        {
            var _loc_1:Number = NaN;
            if (_videoStatus.status == VideoStatus.COMPLETED)
            {
                return totalTime;
            }
            _loc_1 = super.playTime;
            if (_metaData && _metaData.isMP4)
            {
                _loc_1 = _loc_1 + startTime;
            }
            return Math.max(startTime, _loc_1);
        }// end function

        override public function play() : void
        {
            if (_videoStatus.status == VideoStatus.LOADING)
            {
                if (waittingFast == 1)
                {
                    changeStatus(VideoStatus.LOAD_TO_PLAY);
                }
                else
                {
                    netStream.resume();
                    changeStatus(VideoStatus.LOAD_TO_PLAY);
                    if (bugBufferFull)
                    {
                        bufferFullHlr();
                    }
                }
            }
            return;
        }// end function

        public function get hasReady() : Boolean
        {
            return _videoStatus.status >= VideoStatus.READY;
        }// end function

        public function get hasStartPlay() : Boolean
        {
            return _videoStatus.status >= VideoStatus.LOAD_TO_PLAY;
        }// end function

        override public function get totalTime() : Number
        {
            return super.totalTime;
        }// end function

        public function get isCompleted() : Boolean
        {
            return _videoStatus.status == VideoStatus.COMPLETED;
        }// end function

        public function get isFastTudouConnect() : Boolean
        {
            return fastTudou.isConnected;
        }// end function

        override public function onMetaData(param1:Object) : void
        {
            if (_metaData)
            {
                return;
            }
            super.onMetaData(param1);
            if (_aimSeekValue > 0)
            {
                _changeStreamNodeLog = NodeLog.CHANGE_RATE_END;
                if (_lastCurPlayTime > 0 && _aimSeekValue == _lastCurPlayTime)
                {
                    _lastCurPlayTime = -1;
                }
                else if (_skipHeadValue > 0 && _aimSeekValue == _skipHeadValue)
                {
                    _skipHeadValue = -1;
                    dispatchEvent(new PlayerEvent(PlayerEvent.SKIP_HEAD, false, true, ""));
                }
                seekServer(_aimSeekValue * totalTime);
                _aimSeekValue = -1;
            }
            return;
        }// end function

        override public function reset() : void
        {
            basePlayURL = "";
            _cndURL = "";
            isChangedURL = false;
            _hasPlayedTime = 0;
            _aimSeekValue = -1;
            _skipHeadValue = -1;
            _skipTailValue = -1;
            _lastCurPlayTime = -1;
            startKeyIndex = 0;
            playedKeyIndex = 0;
            loadedKeyIndex = 0;
            _changeStreamNodeLog = "";
            _startChangeTime = 0;
            _startBufferTime = 0;
            _seekSize = 0;
            bandManager.reset();
            if (waittingFast == 1)
            {
                removeWaittingFastTudou();
            }
            super.reset();
            return;
        }// end function

        public function set iBaseInfo(param1:IBaseInfo) : void
        {
            _iBaseInfo = param1;
            return;
        }// end function

        public function get hasLoading() : Boolean
        {
            return _videoStatus.status >= VideoStatus.LOADING;
        }// end function

        public function get playSize() : Number
        {
            var _loc_1:KeyInfo = null;
            var _loc_2:KeyInfo = null;
            var _loc_4:Number = NaN;
            var _loc_3:Number = 0;
            if (_metaData)
            {
                if (_metaData.hasKeyFrames)
                {
                    _loc_1 = _metaData.getKeyInfo(playedKeyIndex);
                    if (playedKeyIndex == (_metaData.keyframesLength - 1))
                    {
                        _loc_2 = new KeyInfo(totalSize, totalTime);
                    }
                    else
                    {
                        _loc_2 = _metaData.getKeyInfo((playedKeyIndex + 1));
                    }
                    _loc_4 = (playTime - _loc_1.time) / (_loc_2.time - _loc_1.time);
                    _loc_3 = _loc_1.size + _loc_4 * (_loc_2.size - _loc_1.size);
                }
                else
                {
                    _loc_3 = playTime / totalTime * totalSize;
                }
            }
            return _loc_3;
        }// end function

        public function get startTime() : Number
        {
            return _metaData ? (_metaData.getKeyInfo(startKeyIndex).time) : (0);
        }// end function

        private function removeWaittingFastTudou() : void
        {
            if (fastTimer)
            {
                fastTimer.stop();
                fastTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, waitFastTudouHlr);
            }
            fastTimer = null;
            if (fastTudou.hasEventListener(FastTudouEvent.CHECK_COMPLETE))
            {
                fastTudou.removeEventListener(FastTudouEvent.CHECK_COMPLETE, waitFastTudouHlr);
            }
            return;
        }// end function

        protected function get canSeek() : Boolean
        {
            if (_metaData == null || !_metaData.hasKeyFrames)
            {
                return false;
            }
            return true;
        }// end function

        override public function get totalSize() : Number
        {
            return super.totalSize;
        }// end function

        override protected function playerTimerHlr(event:TimerEvent) : void
        {
            accuratePlayLoadHlr();
            fastTudouHlr();
            bandManagerHlr();
            playProgressHlr();
            skipHlr();
            return;
        }// end function

        public function get playTimePos() : Number
        {
            var _loc_1:* = _metaData ? (playTime / totalTime) : (0);
            return MathUtil.unit(_loc_1);
        }// end function

        override public function seek(param1:Number) : void
        {
            if (_metaData.isMP4)
            {
                param1 = param1 - startTime;
            }
            super.seek(param1);
            if (!canSeek)
            {
                bandManager.setPlayTime(param1);
            }
            return;
        }// end function

        override protected function bufferFullHlr() : void
        {
            dispatch(PlayerEvent.STREAM_BUFFER_FULL, null);
            firstBufferEmpty = true;
            var _loc_1:int = 0;
            var _loc_2:Number = 0;
            if (_videoStatus.status == VideoStatus.LOAD_TO_PLAY)
            {
                _changeStreamNodeLog = NodeLog.VIDEO_FIRST_BUFFER_FULL;
                _aop.addNodeLog(NodeLog.VIDEO_URL, [encodeURIComponent(playURL)]);
                changeStatus(VideoStatus.READY);
                changeStatus(VideoStatus.PLAYING);
            }
            else if (_videoStatus.status < VideoStatus.LOAD_TO_PLAY && !bugBufferFull)
            {
                bugBufferFull = true;
            }
            else if (_videoStatus.status == VideoStatus.BUFFERING)
            {
                changeStatus(VideoStatus.PLAYING);
            }
            if (_changeStreamNodeLog)
            {
                _loc_1 = getTimer() - _startChangeTime;
                _startChangeTime = 0;
                if (_loc_1 > 0)
                {
                    _loc_2 = (loadSize - _seekSize) * 1000 / _loc_1;
                }
                if (_loc_2 < 0)
                {
                    _loc_2 = 0;
                }
                _aop.addNodeLog(_changeStreamNodeLog, [_loc_1, playTime, _loc_2, _iBaseInfo.currRateType]);
                _changeStreamNodeLog = "";
            }
            return;
        }// end function

        public function setSkipHeadTailValue(param1:Number, param2:Number, param3:Number) : void
        {
            _skipHeadValue = param1;
            _skipTailValue = param2;
            _lastCurPlayTime = param3;
            if (_metaData)
            {
                if (playTimePos < param1)
                {
                    seekPercent(_skipHeadValue);
                }
            }
            else if (_lastCurPlayTime > 0)
            {
                _aimSeekValue = param3;
                _skipHeadValue = -1;
            }
            else
            {
                _aimSeekValue = _skipHeadValue;
            }
            return;
        }// end function

        public function get loadTimePos() : Number
        {
            var _loc_1:* = _metaData ? (loadTime / totalTime) : (0);
            return MathUtil.unit(_loc_1);
        }// end function

        public function get startSize() : Number
        {
            return _metaData ? (_metaData.getKeyInfo(startKeyIndex).size) : (0);
        }// end function

        public function get hasPlayedTime() : Number
        {
            return _hasPlayedTime;
        }// end function

        public function set bandCtrl(param1:Number) : void
        {
            bandManager.bandCtrl = param1;
            return;
        }// end function

        private function fastTudouHlr() : void
        {
            var _loc_1:String = null;
            if (fastTudou.canReport && playerTimer.currentCount % 20 == 0 && hasReady && _metaData)
            {
                if (playSize > totalSize && totalSize > 0)
                {
                    return;
                }
                _loc_1 = _iBaseInfo ? (_iBaseInfo.rid) : ("");
                fastTudou.report(_loc_1, playTime, playSize, totalSize / totalTime * 8);
            }
            return;
        }// end function

        override protected function resetBody() : void
        {
            bandManager.reset();
            super.resetBody();
            return;
        }// end function

        public function reLoadPlay(param1:String, param2:MetaData) : void
        {
            if (!param1)
            {
                return;
            }
            if (_videoStatus.status < VideoStatus.LOADING || _videoStatus.status > VideoStatus.COMPLETED)
            {
                return;
            }
            basePlayURL = param1;
            _metaData = param2;
            _startChangeTime = getTimer();
            if (_metaData && _aimSeekValue > 0)
            {
                _changeStreamNodeLog = NodeLog.CHANGE_RATE_END;
                seekServer(_aimSeekValue * totalTime);
                _aimSeekValue = -1;
                refresh();
            }
            else
            {
                startKeyIndex = 0;
                playedKeyIndex = 0;
                loadedKeyIndex = 0;
                _load(param1);
            }
            isChangedURL = true;
            return;
        }// end function

        private function waitFastTudouHlr(event:Event) : void
        {
            waittingFast = 2;
            removeWaittingFastTudou();
            _load(basePlayURL);
            return;
        }// end function

        public function get playURL() : String
        {
            return _playURL;
        }// end function

        public function get isBuffering() : Boolean
        {
            return _videoStatus.status == VideoStatus.BUFFERING;
        }// end function

        public function get isPlaying() : Boolean
        {
            return _videoStatus.status == VideoStatus.PLAYING;
        }// end function

        public function retry(param1:String) : void
        {
            var _loc_2:int = 0;
            if (!param1)
            {
                return;
            }
            if (_videoStatus.status == VideoStatus.ERROR)
            {
                _loc_2 = _videoStatus.lastStatus;
                startKeyIndex = 0;
                playedKeyIndex = 0;
                loadedKeyIndex = 0;
                load(param1);
                if (_loc_2 == VideoStatus.LOAD_TO_PLAY)
                {
                    play();
                }
            }
            return;
        }// end function

        public function get isStartPlay() : Boolean
        {
            return _videoStatus.status == VideoStatus.LOAD_TO_PLAY;
        }// end function

        public function seekPercent(param1:Number, param2:Boolean = false, param3:Number = 0) : void
        {
            if (isNaN(param1) || _metaData == null)
            {
                return;
            }
            if (isCompleted)
            {
                netStream.resume();
                changeStatus(VideoStatus.PLAYING);
            }
            _isDraging = param2;
            var _loc_4:* = param1 * totalTime;
            var _loc_5:* = _metaData.getIndexByTime(_loc_4, param3);
            var _loc_6:* = _metaData.getKeyInfo(_loc_5);
            var _loc_7:* = _metaData.getKeyInfo(_loc_5).size >= startSize && _loc_6.size < loadSize;
            if (_isDraging || !canSeek || _loc_7)
            {
                if (canSeek)
                {
                    _loc_4 = _loc_6.time;
                }
                seek(_loc_4);
            }
            else
            {
                _changeStreamNodeLog = NodeLog.SEEK_END;
                _startChangeTime = getTimer();
                seekServer(_loc_4, param3);
            }
            return;
        }// end function

        private function playProgressHlr() : void
        {
            var _loc_1:Object = {totalTime:totalTime, playTime:playTime, playTimePos:playTimePos, loadTimePos:loadTimePos};
            var _loc_2:* = getTimer();
            if (isPlaying && catchedTime > 0)
            {
                _hasPlayedTime = _hasPlayedTime + (_loc_2 - catchedTime);
            }
            catchedTime = _loc_2;
            return;
        }// end function

        public function get playSizePos() : Number
        {
            var _loc_1:* = _metaData ? (playSize / totalSize) : (0);
            return MathUtil.unit(_loc_1);
        }// end function

        override protected function bufferEmptyHlr() : void
        {
            dispatch(PlayerEvent.STREAM_BUFFER_EMPTY, null);
            if (firstBufferEmpty == false)
            {
                firstBufferEmpty = true;
                return;
            }
            if (loadTime >= playTime + _bufferTime)
            {
                return;
            }
            if (_videoStatus.status == VideoStatus.PLAYING && netStream.bytesLoaded < netStream.bytesTotal)
            {
                _startBufferTime = getTimer();
                changeStatus(VideoStatus.BUFFERING);
            }
            return;
        }// end function

        override protected function changeStatus(param1:int) : void
        {
            if (param1 == VideoStatus.BUFFERING)
            {
                BufferTracker.send(_iBaseInfo, _cndURL, playTime);
            }
            else if (param1 == VideoStatus.ERROR)
            {
                ErrorReportTracker.send(_iBaseInfo.iid, ErrorReportTracker.VIDEO_ERROR, _playURL);
                ErrorTracker.send(_iBaseInfo.sourceId, ErrorTracker.VIDEO_ERROR, 0, _playURL);
            }
            super.changeStatus(param1);
            return;
        }// end function

        override protected function _load(param1:String) : void
        {
            if (fastTudou.isChecked || waittingFast == 2)
            {
                fastTudou.sendVideoInfo(VideoURL.getVideoId(param1), VideoType.getType(param1));
                _cndURL = param1;
                param1 = URLUtil.addKeyValue(param1, "posky", RandString.randId);
                if (_metaData == null)
                {
                    param1 = URLUtil.addParms(param1, "plybgn=1");
                }
                param1 = fastTudou.fastUrl(param1);
                _playURL = param1;
                resetBody();
                netStream.play(param1);
                if (!hasStartPlay || isPaused)
                {
                    netStream.pause();
                }
                dispatch(PlayerEvent.CHANGE_STREAM, _playURL);
                if (isChangedURL)
                {
                    isChangedURL = false;
                    dispatchEvent(new PlayerEvent(PlayerEvent.CHANGE_URL, false, true, _playURL));
                }
            }
            else if (waittingFast == 0)
            {
                fastTudou.addEventListener(FastTudouEvent.CHECK_COMPLETE, waitFastTudouHlr);
                fastTimer = new Timer(100, 1);
                fastTimer.addEventListener(TimerEvent.TIMER_COMPLETE, waitFastTudouHlr);
                fastTimer.start();
                waittingFast = 1;
            }
            else
            {
                return;
            }
            return;
        }// end function

        protected function accuratePlayLoadHlr() : void
        {
            var _loc_1:KeyInfo = null;
            var _loc_2:int = 0;
            if (_metaData && _metaData.hasKeyFrames)
            {
                _loc_2 = playedKeyIndex;
                while (_loc_2 <= (_metaData.keyframesLength - 1))
                {
                    
                    _loc_1 = _metaData.getKeyInfo(_loc_2);
                    if (playTime > _loc_1.time)
                    {
                        _loc_2++;
                        continue;
                    }
                    break;
                }
                playedKeyIndex = (_loc_2 - 1) < 0 ? (0) : ((_loc_2 - 1));
                _loc_2 = loadedKeyIndex;
                while (_loc_2 <= (_metaData.keyframesLength - 1))
                {
                    
                    _loc_1 = _metaData.getKeyInfo(_loc_2);
                    if (loadSize > _loc_1.size)
                    {
                        _loc_2++;
                        continue;
                    }
                    break;
                }
                loadedKeyIndex = (_loc_2 - 1) < 0 ? (0) : ((_loc_2 - 1));
            }
            return;
        }// end function

        public function get loadSizePos() : Number
        {
            var _loc_1:* = _metaData ? (loadSize / totalSize) : (0);
            return MathUtil.unit(_loc_1);
        }// end function

        public function get loadTime() : Number
        {
            var _loc_1:KeyInfo = null;
            var _loc_2:KeyInfo = null;
            var _loc_4:Number = NaN;
            var _loc_3:Number = 0;
            if (_metaData)
            {
                if (_metaData.hasKeyFrames)
                {
                    _loc_1 = _metaData.getKeyInfo(loadedKeyIndex);
                    if (loadedKeyIndex == (_metaData.keyframesLength - 1))
                    {
                        _loc_2 = new KeyInfo(totalSize, totalTime);
                    }
                    else
                    {
                        _loc_2 = _metaData.getKeyInfo((loadedKeyIndex + 1));
                    }
                    _loc_4 = (loadSize - _loc_1.size) / (_loc_2.size - _loc_1.size);
                    _loc_3 = _loc_1.time + _loc_4 * (_loc_2.time - _loc_1.time);
                }
                else
                {
                    _loc_3 = loadSize / totalSize * totalTime;
                }
            }
            return _loc_3;
        }// end function

        protected function seekServer(param1:Number, param2:Number = 0) : void
        {
            var _loc_3:* = _metaData.getIndexByTime(param1, param2);
            var _loc_4:* = _metaData.getKeyInfo(_loc_3);
            startKeyIndex = _loc_3;
            playedKeyIndex = _loc_3;
            loadedKeyIndex = _loc_3;
            var _loc_5:* = basePlayURL;
            var _loc_6:* = Math.ceil(_metaData.isMP4 ? (_loc_4.time) : (_loc_4.size));
            _seekSize = 0;
            if (_loc_6 > 0)
            {
                _seekSize = _loc_6;
                _loc_5 = URLUtil.addKeyValue(_loc_5, "tflvbegin", _loc_6.toString());
            }
            _load(_loc_5);
            return;
        }// end function

        override protected function streamStatusChange() : void
        {
            if (_startBufferTime <= 0)
            {
                return;
            }
            if (_videoStatus.status == VideoStatus.PLAYING || _videoStatus.status == VideoStatus.PAUSED)
            {
                _aop.addNodeLog(NodeLog.VIDEO_BUFFERING_END, [getTimer() - _startBufferTime, playTime]);
                _startBufferTime = 0;
            }
            return;
        }// end function

        override public function load(param1:String) : void
        {
            _startChangeTime = getTimer();
            if (param1)
            {
                basePlayURL = param1;
                changeStatus(VideoStatus.LOADING);
                _metaData = null;
                isChangedURL = true;
                _load(param1);
            }
            return;
        }// end function

        override public function replay() : void
        {
            if (isCompleted)
            {
                seekPercent(0);
            }
            return;
        }// end function

        private function skipHlr() : void
        {
            if (_skipTailValue > 0 && _metaData && int(playTime) == int(_skipTailValue * totalTime))
            {
                dispatchEvent(new PlayerEvent(PlayerEvent.SKIP_TAIL, false, true, ""));
                close();
                changeStatus(VideoStatus.COMPLETED);
            }
            return;
        }// end function

        override protected function completeHlr() : void
        {
            if (_videoStatus.status == VideoStatus.PLAYING)
            {
                if (loadSizePos >= 0.99)
                {
                    changeStatus(VideoStatus.COMPLETED);
                }
                else
                {
                    seekServer(playTime);
                    ErrorReportTracker.send(_iBaseInfo.iid, ErrorReportTracker.STREAM_BREAK, _playURL);
                    ErrorTracker.send(_iBaseInfo.sourceId, ErrorTracker.STREAM_BREAK, 0, _playURL);
                    FastTudouTracker.send(_iBaseInfo, cdnURL, playTime, "sb");
                }
            }
            return;
        }// end function

        override public function close() : void
        {
            basePlayURL = "";
            _hasPlayedTime = 0;
            startKeyIndex = 0;
            playedKeyIndex = 0;
            loadedKeyIndex = 0;
            bandManager.reset();
            _changeStreamNodeLog = "";
            _startChangeTime = 0;
            _startBufferTime = 0;
            _seekSize = 0;
            if (waittingFast == 1)
            {
                removeWaittingFastTudou();
            }
            super.close();
            return;
        }// end function

        public function get isError() : Boolean
        {
            return _videoStatus.status == VideoStatus.ERROR;
        }// end function

    }
}
